package com.tonicgb.shared.config;


import com.tonicgb.shared.common.constants.Constants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import springfox.documentation.builders.*;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;


import java.util.*;
import java.util.function.Predicate;
/**
 * @author zhaiyujin
 * @date 2021-09-06 15:35:23
 * @说明  swagger/Knife4j 文档配置
 */
@Configuration
@EnableOpenApi
public class SwaggerConfig {

    @Value("${swagger.enable}")
    private boolean enableSwagger;
    @Value("${server.servlet.context-path}")
    private String path;
    @Value("${adminPath}")
    private String adminPath;
    @Value("${frontPath}")
    private String frontPath;
    public static final String ROOT = "/";

    @Bean("admin")
    public Docket createAdminRestApi() {

        return new Docket(DocumentationType.OAS_30) //SWAGGER_2,OAS_30
                .pathMapping("/")
                .groupName("admin") //分组
                //.host(domain) //swagger地址
                //.globalRequestParameters(getGlobalRequestParameters())
                .globalResponses(HttpMethod.GET, getGlobalResonseMessage())//自定义code返回状态码
                .globalResponses(HttpMethod.POST, getGlobalResonseMessage())//自定义code返回状态码
                .enable(enableSwagger) // 是否开启
                .select()
                //扫描包的路径
                .apis(RequestHandlerSelectors.basePackage("com.tonicgb.admin.controller"))
                //指定路径处理PathSelectors.any()代表所有的路径,这里指定匹配路径
                .paths(adminPathsAnt())
                .build()
                .protocols(newHashSet("https", "http"))// 支持的通讯协议集合
                .securitySchemes(securitySchemes()) //设置授权信息
                .securityContexts(securityContexts())// 授权信息全局应用
                //.globalOperationParameters(pars) // 针对单个url的验证 如果需要的话
                .apiInfo(apiInfo()); //swagger 基本信息
    }

    @Bean("front")
    public Docket createFrontRestApi() {
        return new Docket(DocumentationType.OAS_30)
                .pathMapping("/")
                .groupName("front") //分组
                //.host(domain) //swagger地址
                .globalResponses(HttpMethod.GET, getGlobalResonseMessage())//自定义code返回状态码
                .globalResponses(HttpMethod.POST, getGlobalResonseMessage())//自定义code返回状态码
                .enable(enableSwagger) // 是否开启
                .select()
                //扫描包的路径
                .apis(RequestHandlerSelectors.basePackage("com.com.tonicgb.front.controller"))
                //指定路径处理PathSelectors.any()代表所有的路径,这里指定匹配路径
                .paths(frontPathsAnt())
                .build()
                .protocols(newHashSet("https", "http"))// 支持的通讯协议集合
                .securitySchemes(securitySchemes()) //设置授权信息
                .securityContexts(securityContexts())// 授权信息全局应用
                //.globalOperationParameters(pars) // 针对单个url的验证 如果需要的话
                .apiInfo(apiInfo()); //swagger 基本信息
    }



    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("TonicGB Swagger")
                .description("TonicGB整合Swagger，用就完了......")
                .version("9.0")
                .contact(new Contact("zhaiyujin","www.baidu.com","aaa@gmail.com"))
                .license("The Apache License")
                .licenseUrl("http://www.fuckyou.org")
                .build();
    }



    //生成通用响应信息（全局返回响应状态）
    private List<Response> getGlobalResonseMessage() {
        //设定全局code为0表示成功，1表示失败
        List<Response> responseList = new ArrayList<>();
        responseList.add(new ResponseBuilder().code("0").description("成功").build());
        responseList.add(new ResponseBuilder().code("1").description("失败").build());
        return responseList;
    }


    private Predicate<String> adminPathsAnt() {
        return PathSelectors.ant(path+adminPath+"/**");
    }

    private Predicate<String> frontPathsAnt() {
        return PathSelectors.ant(path+frontPath+"/**");
    }

    //生成全局通用参数
    private List<RequestParameter> getGlobalRequestParameters() {
        List<RequestParameter> parameters = new ArrayList<>();
        parameters.add(new RequestParameterBuilder()
                .name("appid")
                .description("平台id")
                .required(true)
                .in(ParameterType.QUERY)
                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                .required(false)
                .build());
        parameters.add(new RequestParameterBuilder()
                .name("udid")
                .description("设备的唯一id")
                .required(true)
                .in(ParameterType.QUERY)
                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                .required(false)
                .build());
        parameters.add(new RequestParameterBuilder()
                .name("version")
                .description("客户端的版本号")
                .required(true)
                .in(ParameterType.QUERY)
                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                .required(false)
                .build());
        return parameters;
    }

    /**
     * 设置授权信息
     */
    private List<SecurityScheme> securitySchemes() {
        ApiKey apiKey = new ApiKey(Constants.HEADER_AUTHORIZATION_KEY, Constants.HEADER_AUTHORIZATION_KEY, "header");
        return Collections.singletonList(apiKey);
    }

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> res = new ArrayList<>();
        res.add(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("/.*"))
                .build());
        return res;
    }

    /**
     * 授权信息全局应用
     */
    /*private List<SecurityContext> securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                        .build()
        );
    }*/
    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> res = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", Constants.HEADER_AUTHORIZATION_KEY);
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        res.add(new SecurityReference(Constants.HEADER_AUTHORIZATION_KEY, authorizationScopes));
        return res;
    }

    @SafeVarargs
    private final <T> Set<T> newHashSet(T... ts) {
        if (ts.length > 0) {
            return new LinkedHashSet<>(Arrays.asList(ts));
        }
        return null;
    }


}
